package com.duubee.btframe.service.impl;

import com.baomidou.mybatisplus.annotation.TableField;
import com.duubee.btframe.config.BtFrameProperties;
import com.duubee.btframe.enums.BtSqlType;
import com.duubee.btframe.interfaces.BtIgnore;
import com.duubee.btframe.interfaces.BtOneToMany;
import com.duubee.btframe.utils.BtDateUtil;
import com.duubee.btframe.utils.BtStringUtil;
import com.duubee.btframe.vo.BtCondition;
import com.duubee.btframe.interfaces.BtFKTable;
import com.duubee.btframe.utils.BtFieldUtil;
import com.duubee.btframe.utils.BtFrameUtil;
import com.baomidou.mybatisplus.annotation.TableId;
import com.duubee.btframe.mapper.BtMapper;
import com.duubee.btframe.service.BtCommonService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.binding.BindingException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class BtCommonServiceImpl implements BtCommonService {

    private final Log logger = LogFactory.getLog(BtCommonServiceImpl.class);

    @Resource
    private BtMapper btMapper;

    @Resource
    private BtFrameProperties btFrameProperties;

    @Override
    public <T> IPage<T> queryByPaging(Class<T> t, Page page, BtCondition btCondition) {
        try {

            Field[] fields = BtFieldUtil.getAllFieldsByClass(t);

            //生成查询 SQL语句
            String sql = generateSelectSQL(t, btCondition, MessageFormat.format(" LIMIT {0,number,#},{1,number,#}", (page.getCurrent() - 1) * page.getSize(), page.getSize()), 0);


            //统计
            long count = 0;
            List<T> list = new ArrayList<>();

            if (BtStringUtil.isNotEmpty(sql)) {
                //执行查询
                List<JSONObject> jsonObjects = btMapper.queryList(sql);

                count = this.count(t, btCondition);

                for (JSONObject jsonObject : jsonObjects) {
                    list.add(mappingQueryResult(jsonObject, t, fields, btCondition, false));
                }
            }

            //查询一对多
            queryOneToManyList(t, list, btCondition);

            IPage<T> result = new Page<>();//btMapper.queryByPaging(btPage,sql);
            result.setCurrent(page.getCurrent());
            result.setSize(page.getSize());
            result.setRecords(list);
            result.setTotal(count);


            return result;

        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new BindingException("BtFrame Unknown execution method for: IllegalAccessException  " + e.getMessage());
        } catch (InstantiationException e) {
            e.printStackTrace();
            throw new BindingException("BtFrame Unknown execution method for: InstantiationException  " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BindingException("BtFrame Unknown execution method for: " + e.getMessage());
        }
    }

    @Override
    public <T> T querySingleById(Class<T> t, Serializable id) {
        Field pkField = BtFrameUtil.getTableId(BtFieldUtil.getAllFieldsByClass(t));
        return querySingle(t, BtCondition.create(pkField.getName(), id.toString()));
    }

    @Override
    public <T> T querySingle(Class<T> t, BtCondition btCondition) {
        T backObject = null;

        try {
            Field[] fields = BtFieldUtil.getAllFieldsByClass(t);

            //生成查询语句
            String sql = generateSelectSQL(t, btCondition, null, 0);

            if (BtStringUtil.isEmpty(sql)) {
                return null;
            }

            //执行查询语句
            JSONObject jsonObject = btMapper.querySingle(sql);

            //反射查询结果----
            backObject = mappingQueryResult(jsonObject, t, fields, btCondition, true);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BindingException("BtFrame Unknown execution method for: " + e.getMessage());
        }
        return backObject;
    }

    @Override
    public <T> T querySingleLimit(Class<T> t, BtCondition btCondition) {
        T backObject = null;

        try {
            Field[] fields = BtFieldUtil.getAllFieldsByClass(t);

            //生成查询语句
            String sql = generateSelectSQL(t, btCondition, " LIMIT 0,1", 0);

            if (BtStringUtil.isEmpty(sql)) {
                return null;
            }
            //执行查询语句
            JSONObject jsonObject = btMapper.querySingle(sql);

            //反射查询结果----
            backObject = mappingQueryResult(jsonObject, t, fields, btCondition, true);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BindingException("BtFrame Unknown execution method for: " + e.getMessage());
        }
        return backObject;
    }

    @Override
    public <T> List<T> queryList(Class<T> t) {
        return queryList(t, null);
    }

    @Override
    public <T> List<T> queryList(Class<T> t, BtCondition btCondition) {
        return this.queryList(t, btCondition, true);
    }

    private <T> List<T> queryList(Class<T> t, BtCondition btCondition, boolean queryOneToMany) {
        try {
            Field[] fields = BtFieldUtil.getAllFieldsByClass(t);

            //生成SQL语句
            String sql = generateSelectSQL(t, btCondition, null, 0);

            if (BtStringUtil.isEmpty(sql)) {
                return new ArrayList<>();
            }

            //执行查询
            List<JSONObject> result = btMapper.queryList(sql);

            List<T> list = new ArrayList<>();
            for (JSONObject jsonObject : result) {
                list.add(mappingQueryResult(jsonObject, t, fields, btCondition, false));
            }

            if (queryOneToMany) {
                //查询一对多
                queryOneToManyList(t, list, btCondition);
            }

            return list;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BindingException("BtFrame Unknown execution method for: " + e.getMessage());
        }
        return new ArrayList<>();
    }

    //    @Override
    public <T> boolean save(T entity) {
        try {
            String sql = this.generateInsertSQL(entity, true);

            //字段集合
            Field[] fields = BtFieldUtil.getAllFields(entity);

            Field tableId = BtFrameUtil.getTableId(fields);
            Object key = btMapper.insertReturnKey(sql);
            String keyStr = key.toString();

            tableId.setAccessible(true);
            Class tableIdType = tableId.getType();
            if (tableIdType == int.class || tableIdType == Integer.class) {
                key = Integer.valueOf(keyStr);
            } else if (tableIdType == short.class || tableIdType == Short.class) {
                key = Short.valueOf(keyStr);
            } else if (tableIdType == long.class || tableIdType == Long.class) {
                key = Long.valueOf(keyStr);
            } else if (tableIdType == boolean.class || tableIdType == Boolean.class) {
                key = Boolean.valueOf(keyStr);
            } else if (tableIdType == double.class || tableIdType == Double.class) {
                key = Double.valueOf(keyStr);
            } else if (tableIdType == float.class || tableIdType == Float.class) {
                key = Float.valueOf(keyStr);
            } else if (tableIdType == char.class || tableIdType == Character.class) {
                key = (char) key;
            }
            tableId.set(entity, key);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    //    @Override
    public <T> boolean insert(T entity) {
        return this.save(entity);
    }

    @Override
    public <T> boolean updateById(T entity) {
        return this.updateById(entity, true);
    }

    @Override
    public <T> boolean updateByCondition(T entity, BtCondition btCondition) {
        return this.updateByConditionDN(entity, true, btCondition);
    }

    @Override
    public <T> boolean updateById(T entity, boolean disposeNull) {
        try {
            Field pkField = BtFrameUtil.getTableId(BtFieldUtil.getAllFields(entity));
            pkField.setAccessible(true);
            Object value = pkField.get(entity);
            return this.updateByConditionDN(entity, disposeNull, BtCondition.create(pkField.getName(), value.toString()));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public <T> boolean updateByCondition(T entity, BtCondition btCondition, boolean disposeNull) {
        return this.updateByConditionDN(entity, disposeNull, btCondition);
    }

    private <T> boolean updateByConditionDN(T entity, boolean disposeNull, BtCondition btCondition) {

        try {
            String sql = this.generateUpdateSQL(entity, disposeNull, btCondition);
            if (BtStringUtil.isEmpty(sql)) {
                return false;
            }
            return btMapper.update(sql);

        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public <T> boolean removeById(Class<T> t, Serializable id) {

        Field pkField = BtFrameUtil.getTableId(BtFieldUtil.getAllFieldsByClass(t));

        return this.removeByCondition(t, BtCondition.create(pkField.getName(), id));
    }

    @Override
    public <T> boolean removeByCondition(Class<T> t, BtCondition btCondition) {

        String sql = this.generateDeleteSQL(t, btCondition);
        if (BtStringUtil.isEmpty(sql)) {
            return false;
        }
        return btMapper.delete(sql);

    }

    @Override
    public <T> long count(Class<T> t, BtCondition btCondition) {
        //生成统计SQL语句
        String sqlCount = generateSelectSQL(t, btCondition, null, 1);
        if (BtStringUtil.isEmpty(sqlCount)) {
            return 0;
        }
        return btMapper.queryCount(sqlCount);
    }

    @Override
    public <T> boolean saveOrUpdateByUNIQUE(T t, BtCondition btCondition) {
        try {
            String sql = this.generateSaveOrUpdateSQL(t, true, btCondition);
            return btMapper.update(sql);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 生成查询SQL语句
     *
     * @param t           类型
     * @param btCondition 条件对象
     * @param model       模式 0:生成查询语句 1:生成count语句
     * @return sql语句
     */
    private <T> String generateSelectSQL(Class<T> t, BtCondition btCondition, String limitSql, int model) {
        //如果条件为空，则create一下，下方就不用再判空
        if (btCondition == null) {
            btCondition = BtCondition.create();
        }

        //获取表名
        String tableName = BtFrameUtil.getTableName(t);
        //字段集合
        Field[] fields = BtFieldUtil.getAllFieldsByClass(t);
        //主键字段
//        Field pkField = getTableId(fields);
        StringBuilder stringBuilder = new StringBuilder();

        //查询关键字
        stringBuilder.append("SELECT ");

        //添加是否去重
        if (btCondition.getDistinct()) {
            stringBuilder.append(" distinct ");
        }

        //外键集合
        List<Field> fkFields = getFKTableId(fields);

        if (model == 0) {//生成查询语句
            //添加需要查询的字段
            boolean selectAllField = true;
            if (btCondition.existsField() || btCondition.existsIgnoreField()) {
                for (Field field : fields) {
                    if (!btCondition.existsField(field.getName()) || btCondition.existsIgnoreField(field.getName()) || field.isAnnotationPresent(BtOneToMany.class) || field.isAnnotationPresent(BtFKTable.class)) {
                        continue;
                    }
                    if (!checkExistField(fields, field.getName())) {
                        continue;
                    }

                    selectAllField = false;
                    stringBuilder.append(MessageFormat.format(" `table_{0}`.`{1}`  ,", tableName, BtFrameUtil.getSQLColumnName(field)));
                }
            }
            //判断是否查询所有字段(如果上方存在指定或忽略主表字段，则不能添加*)
            if (selectAllField) {
                stringBuilder.append(MessageFormat.format(" `table_{0}`.*  ", tableName));
            } else {
                stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
            }


            //循环外键表集合--添加需要查询的列并给特定别名
            for (Field field : fkFields) {

                BtFKTable btFKTable = field.getAnnotation(BtFKTable.class);

                //外键字段名
                String fkFieldName = field.getName();

                //外键表实体类类型
                boolean assignFieldInquire = btFKTable != null && btFKTable.fkTable() != Object.class;
                Class<?> classs = assignFieldInquire ? btFKTable.fkTable() : field.getType();

                for (Field fkField : BtFieldUtil.getAllFieldsByClass(classs)) {
                    //判断是否为序列号id
                    if (BtFrameUtil.checkIsModifier(fkField) || fkField.isAnnotationPresent(BtIgnore.class) || fkField.isAnnotationPresent(BtFKTable.class) || fkField.isAnnotationPresent(BtOneToMany.class)) {
                        continue;
                    }

                    TableField tableField = fkField.getAnnotation(TableField.class);
                    if (tableField != null && !tableField.exist()) {
                        continue;
                    }

                    //判断是否为忽略字段
                    if (btFKTable != null && Arrays.stream(btFKTable.ignoreField()).anyMatch(res -> res.equals(fkField.getName()))) {
                        continue;
                    }

                    //如果是指定字段查询   并且不是该指定的字段，则跳过
                    if (assignFieldInquire && (BtStringUtil.isEmpty(btFKTable.column()) || !fkField.getName().equals(btFKTable.column()))) {
                        continue;
                    }

                    //如果是主键则保存
                    if (!fkField.isAnnotationPresent(TableId.class)) {
                        //非主键列则需要查询并给别名
                        stringBuilder.append(MessageFormat.format("  , `table_{0}`.`{1}` {0}_{1}  ", fkFieldName, BtFrameUtil.getSQLColumnName(fkField)));
                    }
                }
                stringBuilder.append(" ");
            }
        } else if (model == 1) {//生成count语句
            //加上查询主表所有列（添加是否去重标识）
            stringBuilder.append(" COUNT(*) ");
        }

        //查询主表
        stringBuilder.append(MessageFormat.format("FROM {0} `table_{0}`  ", tableName));
        //外键连表条件
        StringBuilder fkJoinWhereStr = new StringBuilder();

        //加入连表
        for (Field field : fkFields) {
            BtFKTable btFKTable = field.getAnnotation(BtFKTable.class);
            //外键列名
            String fkCloumnName = btFKTable.value();
            //外键字段名
            String fkFieldName = field.getName();
            //外键表实体类类型
            Class<?> classs = btFKTable.fkTable() == Object.class ? field.getType() : btFKTable.fkTable();
            //外键表名
            String fkTableName = BtFrameUtil.getTableName(classs);//    field.getType().getAnnotation(BtTableName.class).value();
            //外键表主键列
            Field fkTableId = BtFrameUtil.getTableId(BtFieldUtil.getAllFieldsByClass(classs));

            stringBuilder.append(MessageFormat.format("LEFT JOIN `{0}` `table_{1}` ON `table_{1}`.`{2}` = `table_{3}`.`{4}`  ", fkTableName, fkFieldName, BtFrameUtil.getSQLColumnName(fkTableId), tableName, fkCloumnName));

            //判断是否查询逻辑删除数据
            if (!btCondition.getQueryLogicDeleted()) {
                Field logicDeletedField = BtFrameUtil.getLogicDeletedField(BtFieldUtil.getAllFieldsByClass(field.getType()));
                if (logicDeletedField != null) {
                    if (stringBuilder.length() != 0 && BtStringUtil.isNotEmpty(stringBuilder.toString().replace(" ", ""))) {
                        stringBuilder.append(" AND ");
                    }
                    stringBuilder.append(MessageFormat.format("`table_{0}`.`{1}` = {2} ", fkFieldName, BtFrameUtil.getSQLColumnName(logicDeletedField), false));
                }
            }

        }


        //判断是否存在实体类以外的条件
//        if(btCondition != null){

        //加入手动连表
        for (String key : btCondition.keySet()) {
            String joinType;
            if (key.contains(BtFrameUtil.LEFT_JOIN)) {
                joinType = "LEFT JOIN";
            } else if (key.contains(BtFrameUtil.RIGHT_JOIN)) {
                joinType = "RIGHT JOIN";
            } else if (key.contains(BtFrameUtil.INNER_JOIN)) {
                joinType = "INNER JOIN";
            } else {
                joinType = null;
            }

            if (joinType != null) {
                JSONObject jsonObject = btCondition.getJSONObject(key);

                stringBuilder.append(MessageFormat.format("{0} `{1}` `table_{2}` ON `table_{2}`.`{3}` = `table_{4}`.`{5}` ",
                        joinType,
                        jsonObject.getString("tableName"),
                        jsonObject.getString("tableName"),
                        BtFrameUtil.toSQLName(jsonObject.getString("tColumn")),
                        tableName,
                        BtFrameUtil.toSQLName(jsonObject.getString("mColumn"))));


                BtCondition btCondition_LEFTJOIN = jsonObject.getObject("btCondition", BtCondition.class);
                if (btCondition_LEFTJOIN != null) {
                    Class tableType = (Class) jsonObject.get("tableType");
                    Field[] fieldsLeftJoin = BtFieldUtil.getAllFieldsByClass(tableType);
                    for (String key_temp : btCondition_LEFTJOIN.keySet()) {
                        JSONObject back = this.generateSQLCondition(fieldsLeftJoin, key_temp, btCondition_LEFTJOIN.get(key_temp));
                        if (back == null) {
                            return null;
                        }
                        if (back.getBoolean("needContinue")) {
                            continue;
                        }
                        String sqlValue = back.getString("sqlValue");
                        String letStr = back.getString("letStr");
                        String fkTableName = back.getString("fkTableName");
                        Boolean isFkTable = back.getBoolean("isFkTable");

                        stringBuilder.append(MessageFormat.format(" AND `table_{0}`.`{1}`{2}", (isFkTable ? fkTableName : jsonObject.getString("tableName")), BtFrameUtil.toSQLName(letStr), sqlValue));
                    }
                }
                stringBuilder.append(" ");
            }
        }

        //查询条件
        StringBuilder conditionStr = this.generateSQLWhere(fields, tableName, btCondition);

        if (conditionStr == null) {
            return null;
        }
        //查询条件加上外键连表的条件
        if (conditionStr.length() > 0 && fkJoinWhereStr.length() > 0) {
            conditionStr.append(" AND ");
        }
        conditionStr.append(fkJoinWhereStr);

        //如果存在条件则加入到查询语句
        if (conditionStr.length() != 0) {
            stringBuilder.append(MessageFormat.format("WHERE {0}", conditionStr.toString()));
        }

        if (model == 0) {
            //排序
            String column = btCondition.getString(BtFrameUtil.ORDER_COLUMN);
            if (BtStringUtil.isNotEmpty(column)) {

                StringBuilder orderStr = new StringBuilder();
                String[] orderColumn = column.split(",");
                String[] orderArr = btCondition.getString(BtFrameUtil.ORDER_TYPE).split(",");


                for (int i = 0; i < orderColumn.length; i++) {
                    if (BtStringUtil.isEmpty(orderColumn[i])) {
                        continue;
                    }
                    if (orderStr.length() > 0) {
                        orderStr.append(",");
                    }
                    String[] orderColumnSigle = BtStringUtil.stringSplit(orderColumn[i], "$");
                    if (orderColumnSigle.length == 1) {
                        String orderColumnStr = orderColumn[i];
                        List<Field> field = Arrays.stream(fields).filter(f -> f.getName().equals(orderColumnStr)).collect(Collectors.toList());
                        if (field.size() > 0) {
//                            if(orderArr[i].equalsIgnoreCase(BtOrder.NULLDESC.name()) || orderArr[i].equalsIgnoreCase(BtOrder.NULLASC.name())){
//                                orderStr.append(MessageFormat.format("IF(ISNULL(`table_{0}`.`{1}`),{3},{4}) {2}",tableName, BtFrameUtil.getSQLColumnName(field.get(0)),orderArr[i].replace("NULL",""),(orderArr[i].contains("ASC")?"0":"1"),(orderArr[i].contains("ASC")?"1":"0")));
//
//                            }else{
                            orderStr.append(MessageFormat.format("`table_{0}`.`{1}` {3} {2}", tableName, BtFrameUtil.getSQLColumnName(field.get(0)), orderArr[i].replace("NUM", ""), (orderArr[i].contains("NUM") ? "+ 0" : "")));
//                            }
                        }
                    } else {
//                        if(orderArr[i].equalsIgnoreCase(BtOrder.NULLDESC.name()) || orderArr[i].equalsIgnoreCase(BtOrder.NULLASC.name())){
//                            orderStr.append(MessageFormat.format("IF(ISNULL(`table_{0}`.`{1}`),{3},{4}) {2}", BtFrameUtil.toSQLName(orderColumnSigle[0]), BtFrameUtil.toSQLName(orderColumnSigle[1]),orderArr[i].replace("NULL",""),(orderArr[i].contains("ASC")?"0":"1"),(orderArr[i].contains("ASC")?"1":"0")));
//
//                        }else{
                        orderStr.append(MessageFormat.format("`table_{0}`.`{1}` {3} {2}", BtFrameUtil.toSQLName(orderColumnSigle[0]), BtFrameUtil.toSQLName(orderColumnSigle[1]), orderArr[i].replace("NUM", ""), (orderArr[i].contains("NUM") ? "+ 0" : "")));
//                        }


                    }
                }
                String orderS = orderStr.toString().replace("NUM", "");
                if (BtStringUtil.isNotEmpty(orderS)) {
                    stringBuilder.append(MessageFormat.format(" ORDER BY {0}", orderS));
                }
            }


            String groupSql;
            if (BtStringUtil.isNotEmpty(groupSql = this.generateGroupSQL(fields, tableName, btCondition))) {
                stringBuilder.append(" ");
                stringBuilder.append(groupSql);
                stringBuilder.append(" ");
            }

            if (BtStringUtil.isNotEmpty(limitSql)) {
                stringBuilder.append(limitSql);
            }
        }

        String sql = stringBuilder.toString();
        //根据配置打印SQL
        this.printSql(sql, BtSqlType.SELECT);

        return sql;
    }

    /**
     * 生成分组sql
     *
     * @param fields
     * @param tableName
     * @param btCondition
     * @return
     */
    private String generateGroupSQL(Field[] fields, String tableName, BtCondition btCondition) {
        List<String> groupColumns = btCondition.getStringList(BtFrameUtil.GROUP_BY);
        if (groupColumns == null || groupColumns.size() < 1) {
            return null;
        }
        StringBuilder stringBuilder = new StringBuilder();

        groupColumns.stream().forEach(column -> {

            String[] groupColumnSigle = column.split("&");
            if (groupColumnSigle.length > 1) {
                //外键字段
                stringBuilder.append(MessageFormat.format("`table_{0}`.`{1}`,", BtFrameUtil.toSQLName(groupColumnSigle[0]), BtFrameUtil.toSQLName(groupColumnSigle[1])));

            } else {
                //主表字段
                List<Field> fieldX = Arrays.stream(fields).filter(f -> f.getName().equals(column)).collect(Collectors.toList());

                if (fieldX.size() > 0) {
                    stringBuilder.append(MessageFormat.format("`table_{0}`.`{1}`,", tableName, BtFrameUtil.getSQLColumnName(fieldX.get(0))));
                }

            }
        });

        if (stringBuilder.length() > 0) {
            stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());

            return (MessageFormat.format(" GROUP BY {0} ", stringBuilder));
        }

        return stringBuilder.toString();

    }

    //region 生成SaveOrUpdateSQL语句

    /**
     * 生成SaveOrUpdateSQL语句
     *
     * @param entity      更新的实体
     * @param disposeNull 是否处理Null数据
     * @param <T>
     * @return
     * @throws IllegalAccessException
     */
    private <T> String generateSaveOrUpdateSQL(T entity, boolean disposeNull, BtCondition btCondition) throws IllegalAccessException {
        StringBuilder stringBuilder = new StringBuilder();

        Class t = entity.getClass();
        //获取表名
        String tableName = BtFrameUtil.getTableName(t);
        //字段集合
        Field[] fields = BtFieldUtil.getAllFields(entity);


        stringBuilder.append(MessageFormat.format("INSERT INTO `{0}`(", tableName));

        StringBuilder stringBuilderData = new StringBuilder();
        //主键字段
        Field tableIdFileld = BtFrameUtil.getTableId(fields);

        for (Field field : fields) {
            //判断是否为序列号id
            if (BtFrameUtil.checkIsModifier(field) || field.isAnnotationPresent(BtIgnore.class)) {
                continue;
            }

            field.setAccessible(true);
            Object temp = field.get(entity);
            //如果是处理空数据并且字段数据为Null  跳过··    如果是主键列，并且数据为Null 也是跳过处理
            if ((disposeNull && temp == null) || (tableIdFileld.getName().equals(field.getName()) && temp == null)) {
                continue;
            }

            stringBuilder.append(MessageFormat.format("`{0}`", BtFrameUtil.getSQLColumnName(field)));
            stringBuilder.append(",");

            if (temp == null) {
                stringBuilderData.append("NULL");
            } else {
                if (field.getType() == Boolean.class || field.getType() == boolean.class) {
                    stringBuilderData.append(temp.toString());
                } else if (field.getType() == String[].class || field.getType() == Integer[].class) {
                    stringBuilderData.append(MessageFormat.format("\"{0}\"", JSONArray.toJSONString(temp).replace("\"", "\\\"")));
                } else {
                    stringBuilderData.append(MessageFormat.format("\"{0}\"", temp.toString()));
                }
            }
            stringBuilderData.append(",");
        }

        stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
        stringBuilderData.delete(stringBuilderData.length() - 1, stringBuilderData.length());

        stringBuilder.append(MessageFormat.format(")   VALUES({0})", stringBuilderData.toString()));

        stringBuilder.append(" ON DUPLICATE KEY UPDATE ");

        stringBuilderData = new StringBuilder();

        if (btCondition != null && btCondition.keySet().size() > 0) {

            for (Field field : fields) {
                if (field != null) {

                    if (btCondition.keySet().contains(field.getName())) {
                        continue;
                    }
                    //判断是否为序列号id
                    if (BtFrameUtil.checkIsModifier(field) || field.isAnnotationPresent(BtIgnore.class)) {
                        continue;
                    }

                    field.setAccessible(true);
                    Object temp = field.get(entity);

                    //如果是处理空数据并且字段数据为Null  跳过··    如果是主键列，并且数据为Null 也是跳过处理
                    if ((disposeNull && temp == null) || (tableIdFileld.getName().equals(field.getName()) && temp == null)) {
                        continue;
                    }

                    stringBuilderData.append(MessageFormat.format("`{0}`", BtFrameUtil.getSQLColumnName(field)));
                    stringBuilderData.append(" = ");
                    if (temp == null) {
                        stringBuilderData.append("NULL");
                    } else {
                        if (field.getType() == Boolean.class || field.getType() == boolean.class) {
                            stringBuilderData.append(temp.toString());
                        } else if (field.getType() == String[].class || field.getType() == Integer[].class) {
                            stringBuilderData.append(MessageFormat.format("\"{0}\"", JSONArray.toJSONString(temp).replace("\"", "\\\"")));
                        } else {
                            stringBuilderData.append(MessageFormat.format("\"{0}\"", temp.toString()));
                        }
                    }

                    stringBuilderData.append(",");

                }
            }
        }

        if (stringBuilderData.length() > 0) {
            stringBuilderData.delete(stringBuilderData.length() - 1, stringBuilderData.length());
        }
        stringBuilderData.append(";");

        stringBuilder.append(stringBuilderData);


        String sql = stringBuilder.toString();
        //根据配置打印SQL
        this.printSql(sql, BtSqlType.INSERT);

        return sql;
    }
    //endregion

    //region 生成插入SQL语句

    /**
     * 生成插入SQL语句
     *
     * @param entity      更新的实体
     * @param disposeNull 是否处理Null数据
     * @param <T>
     * @return
     * @throws IllegalAccessException
     */
    private <T> String generateInsertSQL(T entity, boolean disposeNull) throws IllegalAccessException {
        StringBuilder stringBuilder = new StringBuilder();

        Class t = entity.getClass();
        //获取表名
        String tableName = BtFrameUtil.getTableName(t);
        //字段集合
        Field[] fields = BtFieldUtil.getAllFields(entity);


        stringBuilder.append(MessageFormat.format("INSERT INTO `{0}`(", tableName));

        StringBuilder stringBuilderData = new StringBuilder();
        //主键字段
        Field tableIdFileld = BtFrameUtil.getTableId(fields);

        for (Field field : fields) {
            //判断是否为序列号id
            if (BtFrameUtil.checkIsModifier(field) || field.isAnnotationPresent(BtIgnore.class)) {
                continue;
            }

            field.setAccessible(true);
            Object temp = field.get(entity);
            //如果是处理空数据并且字段数据为Null  跳过··    如果是主键列，并且数据为Null 也是跳过处理
            if ((disposeNull && temp == null) || (tableIdFileld.getName().equals(field.getName()) && temp == null)) {
                continue;
            }

            stringBuilder.append(MessageFormat.format("`{0}`", BtFrameUtil.getSQLColumnName(field)));
            stringBuilder.append(",");

            if (temp == null) {
                stringBuilderData.append("NULL");
            } else {
                if (field.getType() == Boolean.class || field.getType() == boolean.class) {
                    stringBuilderData.append(temp.toString());
                } else if (field.getType() == String[].class || field.getType() == Integer[].class) {
                    stringBuilderData.append(MessageFormat.format("\"{0}\"", JSONArray.toJSONString(temp).replace("\"", "\\\"")));
                } else {
                    stringBuilderData.append(MessageFormat.format("\"{0}\"", temp.toString()));
                }
            }
            stringBuilderData.append(",");
        }

        stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
        stringBuilderData.delete(stringBuilderData.length() - 1, stringBuilderData.length());

        stringBuilder.append(MessageFormat.format(")   VALUES({0})", stringBuilderData.toString()));

        String sql = stringBuilder.toString();
        //根据配置打印SQL
        this.printSql(sql, BtSqlType.INSERT);

        return sql;
    }
    //endregion

    //region 生成更新SQL语句

    /**
     * 生成更新SQL语句
     *
     * @param entity      更新的实体
     * @param disposeNull 是否处理Null数据  (为Null跳过)
     * @param <T>
     * @return
     * @throws IllegalAccessException
     */
    private <T> String generateUpdateSQL(T entity, boolean disposeNull, BtCondition btCondition) throws IllegalAccessException {
        StringBuilder stringBuilder = new StringBuilder();

        Class t = entity.getClass();
        //获取表名
        String tableName = BtFrameUtil.getTableName(t);
        //字段集合
        Field[] fields = BtFieldUtil.getAllFields(entity);

        //主键字段
        Field tableIdFileld = BtFrameUtil.getTableId(fields);

        stringBuilder.append(MessageFormat.format("UPDATE `{0}` table_{0} SET ", tableName));


        for (Field field : fields) {
            //判断是否为序列号id
            if (BtFrameUtil.checkIsModifier(field) || field.isAnnotationPresent(BtIgnore.class)) {
                continue;
            }

            field.setAccessible(true);
            Object temp = field.get(entity);
            //如果是处理空数据并且字段数据为Null  跳过··    如果是主键列，并且数据为Null 也是跳过处理
            if ((disposeNull && temp == null) || (tableIdFileld.getName().equals(field.getName()) && temp == null)) {
                continue;
            }

            stringBuilder.append(MessageFormat.format("`{0}` = ", BtFrameUtil.getSQLColumnName(field)));

            if (temp == null) {
                stringBuilder.append("NULL");
            } else {
                if (field.getType() == Boolean.class || field.getType() == boolean.class) {
                    stringBuilder.append(temp.toString());
                } else if (field.getType() == String[].class || field.getType() == Integer[].class) {
                    stringBuilder.append(MessageFormat.format("\"{0}\"", JSONArray.toJSONString(temp).replace("\"", "\\\"")));
                } else {
                    stringBuilder.append(MessageFormat.format("\"{0}\"", temp.toString()));
                }
            }

            stringBuilder.append(",");

        }

        stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());


        //-------------这里开始处理更新条件------------------


        //查询条件
        StringBuilder conditionStr = this.generateSQLWhere(fields, tableName, btCondition);
        if (conditionStr == null) {
            return null;
        }

        //如果存在条件则加入到查询语句
        if (conditionStr.length() != 0) {
            stringBuilder.append(MessageFormat.format(" WHERE {0}", conditionStr.toString()));
        }


        String sql = stringBuilder.toString();

        //根据配置打印SQL
        this.printSql(sql, BtSqlType.UPDATE);

        return sql;


    }
    //endregion

    //region 生成删除SQL语句

    /**
     * 生成删除SQL语句
     *
     * @param t   更新实体类型
     * @param <T>
     * @return
     * @throws IllegalAccessException
     */
    private <T> String generateDeleteSQL(Class<T> t, BtCondition btCondition) {
        StringBuilder stringBuilder = new StringBuilder();

        //获取表名
        String tableName = BtFrameUtil.getTableName(t);
        //字段集合
        Field[] fields = BtFieldUtil.getAllFieldsByClass(t);


        stringBuilder.append(MessageFormat.format("DELETE `table_{0}` FROM `{0}` `table_{0}` ", tableName));


        //-------------处理条件------------------
        StringBuilder conditionStr = this.generateSQLWhere(fields, tableName, btCondition);

        if (conditionStr == null) {
            return null;
        }

        //如果存在条件则加入到查询语句
        if (conditionStr.length() != 0) {
            stringBuilder.append(MessageFormat.format("WHERE {0}", conditionStr.toString()));
        }


        String sql = stringBuilder.toString();
        //根据配置打印SQL
        this.printSql(sql, BtSqlType.DELETE);

        return sql;


    }
    //endregion

    //region 生成条件部分的SQL

    /**
     * 生成条件部分的SQL
     *
     * @param fields
     * @param tableName
     * @param btCondition
     * @return
     */
    private StringBuilder generateSQLWhere(Field[] fields, String tableName, BtCondition btCondition) {
        StringBuilder conditionStr = new StringBuilder();

        for (String key : btCondition.keySet()) {
            Object value;
            //如果不存在值则结束
            if ((value = btCondition.get(key)) == null) {
                return null;
            }

            boolean isFkTable = false;
            String fkTableName = "";
            String sqlValue = "";
            String letStr = "";


            //判断是否是or条件
            if (!key.contains(BtFrameUtil.OR) && !key.contains(BtFrameUtil.LEFT_JOIN)) {

                JSONObject back = this.generateSQLCondition(fields, key, value);
                if (back == null) {
                    return null;
                }
                if (back.getBoolean("needContinue")) {
                    continue;
                }
                sqlValue = back.getString("sqlValue");
                letStr = back.getString("letStr");
                fkTableName = back.getString("fkTableName");
                isFkTable = back.getBoolean("isFkTable");

                if (conditionStr.length() != 0) {
                    conditionStr.append("  AND ");
                }


                if (sqlValue.equals(BtFrameUtil.TODAY)) {
                    conditionStr.append(MessageFormat.format("to_days(`table_{0}`.`{1}`) = to_days(now()); ", (isFkTable ? fkTableName : tableName), BtFrameUtil.toSQLName(letStr)));
                } else {
                    conditionStr.append(MessageFormat.format(" `table_{0}`.`{1}`{2}", (isFkTable ? fkTableName : tableName), BtFrameUtil.toSQLName(letStr), sqlValue));
                }

            } else if (!key.contains(BtFrameUtil.LEFT_JOIN)) {
                //or条件处理
                BtCondition[] btConditionOr = btCondition.getBtConditionArr(key);
                StringBuilder stringBuilderOr = new StringBuilder();
                for (BtCondition tempOr : btConditionOr) {
                    StringBuilder tempOrAnd = new StringBuilder();
                    for (String orKey : tempOr.keySet()) {

                        JSONObject back = this.generateSQLCondition(fields, orKey, tempOr.get(orKey));
                        if (back == null) {
                            return null;
                        }
                        if (back.getBoolean("needContinue")) {
                            continue;
                        }
                        sqlValue = back.getString("sqlValue");
                        letStr = back.getString("letStr");
                        fkTableName = back.getString("fkTableName");
                        isFkTable = back.getBoolean("isFkTable");


                        if (tempOrAnd.length() != 0) {
                            tempOrAnd.append(" AND ");
                        }

                        if (sqlValue.equals(BtFrameUtil.TODAY)) {
                            tempOrAnd.append(MessageFormat.format("to_days(`table_{0}`.`{1}`) = to_days(now()); ", (isFkTable ? fkTableName : tableName), BtFrameUtil.toSQLName(letStr)));
                        } else {
                            tempOrAnd.append(MessageFormat.format(" `table_{0}`.`{1}`{2}", (isFkTable ? fkTableName : tableName), BtFrameUtil.toSQLName(letStr), sqlValue));
                        }
                    }
                    if (tempOrAnd.length() > 0) {
                        if (stringBuilderOr.length() != 0) {
                            stringBuilderOr.append(" OR ");
                        }

                        stringBuilderOr.append("(");
                        stringBuilderOr.append(tempOrAnd);
                        stringBuilderOr.append(")");
                    }
                }

                if (conditionStr.length() != 0) {
                    conditionStr.append(" AND ");
                }
                conditionStr.append("(");
                conditionStr.append(stringBuilderOr);
                conditionStr.append(")");
            }
        }

        //判断是否查询逻辑删除数据
        if (!btCondition.getQueryLogicDeleted()) {
            //判断是否包含逻辑删除字段
            Field logicDeletedField = BtFrameUtil.getLogicDeletedField(fields);
            if (logicDeletedField != null) {
                if (conditionStr.length() != 0 && BtStringUtil.isNotEmpty(conditionStr.toString().replace(" ", ""))) {
                    conditionStr.append(" AND ");
                }
                conditionStr.append(MessageFormat.format("`table_{0}`.`{1}` = {2}", tableName, BtFrameUtil.getSQLColumnName(logicDeletedField), false));
            }
        }

        return conditionStr;
    }
    //endregion

    //region 生成语句条件

    /**
     * 生成语句条件
     *
     * @param fields
     * @param key
     * @param value
     * @return
     */
    private JSONObject generateSQLCondition(Field[] fields, String key, Object value) {
        JSONObject jsonObject = new JSONObject();

        jsonObject.put("needContinue", false);
        String sqlValue = "'" + value + "'";

        if (value != null && (value.getClass() == boolean.class || value.getClass() == Boolean.class)) {
            sqlValue = value.toString();
        }

        String letStr;

        boolean isFkTable = false;
        String fkTableName = "";
        if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.BEGIN)) != null) {
            String temp = "";
            if (value.getClass() == Date.class) {
                temp = BtDateUtil.parseDateToStr((Date) value, BtDateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS, value.toString());
            } else if (value.getClass() == String.class) {
                Date date = BtDateUtil.strToDate(value.toString() + " 00:00:00");
                temp = BtDateUtil.parseDateToStr(date, BtDateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS, value.toString());
            }
            sqlValue = " >= '" + temp + "'";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.END)) != null) {

            String temp = "";
            if (value.getClass() == Date.class) {
                temp = BtDateUtil.parseDateToStr((Date) value, BtDateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS, value.toString());
            } else if (value.getClass() == String.class) {
                Date date = BtDateUtil.strToDate(value.toString() + " 23:59:59");
                temp = BtDateUtil.parseDateToStr(date, BtDateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS, value.toString());
            }

            sqlValue = " <= '" + temp + "'";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.TODAY)) != null) {
            sqlValue = BtFrameUtil.TODAY;
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.GT_EQ)) != null) {
            sqlValue = " >= " + sqlValue;
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.LT_EQ)) != null) {
            sqlValue = " <= " + sqlValue;
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.ISNULL)) != null) {
            sqlValue = " is null ";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.ISNOTNULL)) != null) {
            sqlValue = " is not null ";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.LEFT_LIKE)) != null) {
            sqlValue = " LIKE CONCAT('%'," + sqlValue + ") ";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.RIGHT_LIKE)) != null) {
            sqlValue = " LIKE CONCAT(" + sqlValue + ",'%') ";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.NOTLIKE)) != null) {
            sqlValue = " NOT LIKE CONCAT('%'," + sqlValue + ",'%') ";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.LIKE)) != null) {
            sqlValue = " LIKE CONCAT('%'," + sqlValue + ",'%') ";
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.GT)) != null) {
            sqlValue = " > " + sqlValue;
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.LT)) != null) {
            sqlValue = " < " + sqlValue;
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.NE)) != null) {
            sqlValue = " != " + sqlValue;
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.LT)) != null) {
            sqlValue = " < " + sqlValue;
        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.IN)) != null) {
            Object[] arr;
            if (value != null && (arr = (Object[]) value).length > 0) {
                StringBuilder stringBuilder = new StringBuilder();
                for (Object o : arr) {
                    if (o != null) {
                        stringBuilder.append("'");
                        stringBuilder.append(o.toString());
                        stringBuilder.append("'");
                        stringBuilder.append(",");
                    }
                }
                sqlValue = " IN(" + stringBuilder.substring(0, stringBuilder.length() - 1) + ")";
            } else {
                return null;
            }

        } else if ((letStr = BtStringUtil.getLeftStr(key, BtFrameUtil.NOTIN)) != null) {
            Object[] arr;
            if (value != null && (arr = (Object[]) value).length > 0) {
                StringBuilder stringBuilder = new StringBuilder();
                for (Object o : arr) {
                    if (o != null) {
                        stringBuilder.append("'");
                        stringBuilder.append(o.toString());
                        stringBuilder.append("'");
                        stringBuilder.append(",");
                    }
                }
                sqlValue = " NOT IN(" + stringBuilder.substring(0, stringBuilder.length() - 1) + ")";
            } else {
                return null;
            }
        } else {
            letStr = key;

            Field field = this.getFieldByName(fields, key);

            if (field != null) {
                if (field.getType() == Boolean.class || field.getType() == boolean.class) {
                    sqlValue = value.toString();
                }
            }
            sqlValue = " = " + sqlValue;
        }

        //判断该条件是否为实体类字段(如果不存在该字段则跳过本次循环)
        if (!checkExistField(fields, letStr)) {
            //判断是否为外键字段
            isFkTable = checkFkFieldTableName(fields, letStr);
            if (!isFkTable) {
                jsonObject.put("needContinue", true);
            } else {
                //是外键字段（多对一、一对多都有可能）
                String[] name = BtStringUtil.stringSplit(letStr, "$");
                fkTableName = name[0];
                letStr = name[1];
            }
        }

        jsonObject.put("fkTableName", fkTableName);
        jsonObject.put("letStr", letStr);
        jsonObject.put("sqlValue", sqlValue);
        jsonObject.put("isFkTable", isFkTable);

        return jsonObject;
    }
    //endregion


    //region 映射查询结果

    /**
     * 映射查询结果
     *
     * @param jsonObject 对象
     * @param t          实体类型
     * @param fields     字段集合
     * @return 处理后对象结果
     * @throws IllegalAccessException 异常
     */
    private <T> T mappingQueryResult(JSONObject jsonObject, Class<T> t, Field[] fields, BtCondition btCondition, boolean queryOneToMany) throws IllegalAccessException, InstantiationException {
        T back = null;
        //如果查询结果不为空则映射
        if (jsonObject != null) {
            back = t.newInstance();
            for (Field field : fields) {
                //判断是否为序列号id
                if (BtFrameUtil.checkIsModifier(field) || field.isAnnotationPresent(BtIgnore.class) || (btCondition != null && btCondition.existsIgnoreField(field.getName()) && !btCondition.existsField(field.getName()))) {
                    continue;
                }

                Class<?> type = field.getType();
                field.setAccessible(true);

                //非外键列(普通列)直接设置值
                if (!field.isAnnotationPresent(BtFKTable.class) && !field.isAnnotationPresent(BtIgnore.class) && !field.isAnnotationPresent(BtOneToMany.class)) {
                    String key = BtFrameUtil.getSQLColumnName(field);
                    if (!jsonObject.containsKey(key)) {
                        continue;
                    }

                    //特殊数据类型，特殊处理一下----
                    if (type == LocalDateTime.class) {
                        Date value = jsonObject.getObject(key, Date.class);
                        if (value != null) {
                            field.set(back, LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault()));
                        }
                    } else if (type == LocalDate.class) {
                        Date value = jsonObject.getObject(key, Date.class);
                        if (value != null) {
                            field.set(back, value.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
                        }
                    } else if (type == String[].class) {
                        String val = jsonObject.getString(key);
                        if (!BtStringUtil.isEmpty(val)) {
                            JSONArray jsonArray = JSONArray.parseArray(val);
                            String[] tempArr = new String[]{};
                            field.set(back, jsonArray.toArray(tempArr));
                        }
                    } else if (type == Integer[].class) {
                        String val = jsonObject.getString(key);
                        if (!BtStringUtil.isEmpty(val)) {
                            JSONArray jsonArray = JSONArray.parseArray(val);
                            Integer[] tempArr = new Integer[]{};
                            field.set(back, jsonArray.toArray(tempArr));
                        }
                    } else {
                        Object value = jsonObject.getObject(key, type);
                        if (value == null) {
                            continue;
                        }
                        field.set(back, value);
                    }

                } else if (field.isAnnotationPresent(BtFKTable.class)) {

                    BtFKTable btFKTable = field.getAnnotation(BtFKTable.class);

                    //外键列处理---
                    Field[] tempFields = BtFieldUtil.getAllFieldsByClass(type);

                    //外键字段名
                    String fkfieldName = field.getName();


                    if (btFKTable.fkTable() != Object.class && BtStringUtil.isNotEmpty(btFKTable.column())) {

                        field.set(back, jsonObject.getString(field.getName() + "_" + BtFrameUtil.toSQLName(btFKTable.column())));

                    } else {

                        //子对象(使用JSONObject来代接)
                        JSONObject tempObject = new JSONObject();
                        Object pkObject = null;
                        Field fkTableId = BtFrameUtil.getTableId(tempFields);
                        for (Field tempField : tempFields) {
                            //判断是否为序列号id
                            if (BtFrameUtil.checkIsModifier(tempField) || tempField.isAnnotationPresent(BtIgnore.class)) {
                                continue;
                            }
                            tempField.setAccessible(true);
                            String tempName = tempField.getName();
                            Class<?> tempType = tempField.getType();
                            //SQL查询结果集列的别名
                            String colAlias;
                            //如果是外键主键列则使用主表的字段
                            if (tempField.getName().equals(fkTableId.getName())) {
                                colAlias = field.getAnnotation(BtFKTable.class).value();
                                pkObject = jsonObject.getObject(colAlias, tempType);
                                tempObject.put(tempName, pkObject);
                            } else {  //如果是外键的普通列，则使用生成规则的别名
                                colAlias = fkfieldName + "_" + BtFrameUtil.getSQLColumnName(tempField);
                                tempObject.put(tempName, jsonObject.getObject(colAlias, tempType));
                            }
                        }
                        if (pkObject != null) {
                            field.set(back, tempObject.toJavaObject(type));
                        }
                    }

                } else if (queryOneToMany && field.isAnnotationPresent(BtOneToMany.class) && field.getType() == List.class) {//一对多
                    queryOneToMany(jsonObject, back, fields, btCondition, field);
                }
            }
        }

        return back;
    }
    //endregion


    /**
     * 查询一对多
     *
     * @param jsonObject
     * @param back
     * @param fields
     * @param btCondition
     * @param field
     * @param <T>
     * @throws IllegalAccessException
     */
    private <T> void queryOneToMany(JSONObject jsonObject, T back, Field[] fields, BtCondition btCondition, Field field) throws IllegalAccessException {
        //一对多的数据库关联列名
        String sqlColumnNameOTM = field.getAnnotation(BtOneToMany.class).value();
        //一对多实体类注解添加的条件
        String[] btConditionOTMStr = field.getAnnotation(BtOneToMany.class).btCondition();
        String[] ignoreFieldOTMStr = field.getAnnotation(BtOneToMany.class).ignoreField();
        Object objcet = jsonObject.get(BtFrameUtil.getSQLColumnName(BtFrameUtil.getTableId(fields)));
        if (objcet != null) {
            Class<?> classOTM = field.getType();
            // 集合List元素
            if (classOTM.equals(List.class)) {
                // 当前集合的泛型类型
                Type genericType = field.getGenericType();
                if (null == genericType) {
                    throw new RuntimeException("BtFrame GenericType is null");
                }
                if (genericType instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) genericType;
                    // 得到泛型里的class类型对象
                    classOTM = (Class<?>) pt.getActualTypeArguments()[0];
                }
            }
            BtCondition btConditionOTM = BtCondition.create(BtFrameUtil.toEntityName(sqlColumnNameOTM), objcet).ignoreField(ignoreFieldOTMStr);
            //处理实体类注解的条件
            if (btConditionOTMStr.length > 0) {
                for (String temp : btConditionOTMStr) {
                    if (!BtStringUtil.isEmpty(temp)) {
                        String[] tempBtCondition = BtStringUtil.stringSplit(temp, ":");
                        if (tempBtCondition.length == 2) {
                            btConditionOTM.eq(tempBtCondition[0], tempBtCondition[1]);
                        }
                    }
                }
            }
            //处理代码添加的条件
            for (String key : btCondition.keySet()) {
                if (key.indexOf(field.getName()) == 0) {
                    String[] name = BtStringUtil.stringSplit(key, "$");
                    btConditionOTM.eq(name[1], btCondition.getString(key));
                }
            }

            List<?> list = this.queryList(classOTM, btConditionOTM, false);
            field.set(back, list);
        }
    }

    private <T> void queryOneToManyList(Class<T> tClass, List<T> list, BtCondition btCondition) throws IllegalAccessException {

        Field[] fields = BtFieldUtil.getAllFieldsByClass(tClass);

        List<Field> fieldList_OTM = Arrays.stream(fields).filter(field -> field.isAnnotationPresent(BtOneToMany.class) && field.getType() == List.class).collect(Collectors.toList());

        Field field_ID = BtFrameUtil.getTableId(fields);
        for (Field field : fieldList_OTM) {
            //一对多的数据库关联列名
            String sqlColumnNameOTM = field.getAnnotation(BtOneToMany.class).value();
            //一对多实体类注解添加的条件
            String[] btConditionOTMStr = field.getAnnotation(BtOneToMany.class).btCondition();
            String[] ignoreFieldOTMStr = field.getAnnotation(BtOneToMany.class).ignoreField();

            List<Object> idValue = new ArrayList<>();

            list.forEach(entity -> {
                try {
                    idValue.add(BtFieldUtil.Get.get(entity, field_ID));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            });

            String columnName = BtFrameUtil.toEntityName(sqlColumnNameOTM);

            BtCondition btConditionOTM = BtCondition.create().in(columnName, idValue).ignoreField(ignoreFieldOTMStr);
            //处理实体类注解的条件
            if (btConditionOTMStr.length > 0) {
                for (String temp : btConditionOTMStr) {
                    if (!BtStringUtil.isEmpty(temp)) {
                        String[] tempBtCondition = BtStringUtil.stringSplit(temp, ":");
                        if (tempBtCondition.length == 2) {
                            btConditionOTM.eq(tempBtCondition[0], tempBtCondition[1]);
                        }
                    }
                }
            }
            if (btCondition != null) {
                //处理代码添加的条件
                for (String key : btCondition.keySet()) {
                    if (key.indexOf(field.getName()) == 0) {
                        String[] name = BtStringUtil.stringSplit(key, "$");
                        btConditionOTM.eq(name[1], btCondition.getString(key));
                    }
                }
            }

            Class<?> classOTM = field.getType();
            // 集合List元素
            if (classOTM.equals(List.class)) {
                // 当前集合的泛型类型
                Type genericType = field.getGenericType();
                if (null == genericType) {
                    throw new RuntimeException("BtFrame GenericType is null");
                }
                if (genericType instanceof ParameterizedType) {
                    ParameterizedType pt = (ParameterizedType) genericType;
                    // 得到泛型里的class类型对象
                    classOTM = (Class<?>) pt.getActualTypeArguments()[0];
                }
            }

            Field fieldOTM = BtFieldUtil.getFieldByNameAndClass(classOTM, columnName);
            if (fieldOTM == null) {
                continue;
            }
            //清除指定查询外键忽略字段
            if (btConditionOTM.existsIgnoreField(columnName)) {
                btConditionOTM.clearIgnoreField(columnName);
            }
            List<?> resultList = this.queryList(classOTM, btConditionOTM, false);

//            Field fieldOTMId = BtFrameUtil.getTableId(BtFieldUtil.getAllFieldsByClass(classOTM));

            for (T entity : list) {
                List<Object> resultTempList = new ArrayList<>();
                for (int i = 0; i < resultList.size(); i++) {

                    Object resultObject = resultList.get(i);
                    String str = BtFieldUtil.Get.getString(resultObject, fieldOTM);
                    if (BtStringUtil.isNotEmpty(str) && str.equals(BtFieldUtil.Get.getString(entity, field_ID))) {
                        resultTempList.add(resultObject);
                    }
                }
                BtFieldUtil.Set.setAuto(entity, field, resultTempList);
            }
        }


    }


    //region 取出外键列

    /**
     * 取出外键列
     *
     * @param fields 字段集合
     * @return 外键列
     */
    private List<Field> getFKTableId(Field[] fields) {
        List<Field> fildList = new ArrayList<>();
        for (Field f : fields) {
            if (f.isAnnotationPresent(BtFKTable.class) && !f.isAnnotationPresent(BtIgnore.class)) {
                fildList.add(f);
            }
        }
        return fildList;
    }
    //endregion

    //region 通过名字取出列

    /**
     * 通过名字取出列
     *
     * @param fields 字段集合
     * @param name   需要查找的字段名
     * @return 外键列
     */
    private Field getFieldByName(Field[] fields, String name) {
        for (Field f : fields) {
            if (f.getName().equals(name) && !f.isAnnotationPresent(BtIgnore.class)) {
                return f;
            }
        }
        return null;
    }
    //endregion


    //region 判断是否存在该字段

    /**
     * 判断是否存在该字段
     *
     * @param fields    字段集合
     * @param fieldName 判断的字段名
     * @return 是否存在
     */
    private boolean checkExistField(Field[] fields, String fieldName) {
        if (!(fields == null || fields.length == 0 || fieldName == null || fieldName.isEmpty())) {
            for (Field field : fields) {
                //等于判断的字段名并且不存在忽略注解并且不存在一对多注解
                if (field.getName().equals(fieldName) && !field.isAnnotationPresent(BtIgnore.class) && !field.isAnnotationPresent(BtOneToMany.class)) {
                    return true;
                }
            }
        }
        return false;
    }
    //endregion

    //region 判断是否为外键

    /**
     * 判断是否为外键
     *
     * @param fields    字段集合
     * @param fieldName 判断的字段名
     * @return 是否存在
     */
    private boolean checkFkFieldTableName(Field[] fields, String fieldName) {
        if (!(fields == null || fields.length == 0 || fieldName == null || fieldName.isEmpty())) {
            for (Field field : fields) {
                if (field.isAnnotationPresent(BtFKTable.class) && !field.isAnnotationPresent(BtIgnore.class)) {
                    String[] name = BtStringUtil.stringSplit(fieldName, "$");
                    if (name.length >= 2 && field.getName().equalsIgnoreCase(name[0])) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    //endregion


    //region 打印sql

    /**
     * 打印sql
     *
     * @param sql
     * @param btSqlType
     */
    private void printSql(String sql, BtSqlType btSqlType) {
        String log = this.btFrameProperties.getLog();
        if (!log.equalsIgnoreCase("none")) {

            switch (btSqlType) {
                case All:
                case INSERT:
                case SELECT:
                case DELETE:
                case UPDATE:
                    break;
                default:
                    sql = null;
                    break;
            }

            if (sql != null) {

                switch (log.toLowerCase()) {
                    case "info":
                        logger.info(sql);
                        break;
                    case "debug":
                        logger.debug(sql);
                        break;
                    case "error":
                        logger.error(sql);
                        break;
                    case "fatal":
                        logger.fatal(sql);
                        break;
                }
            }
        }
    }
    //endregion

}
